package com.abso.sunlight.explorer;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

/**
 * Miscellaneous search utilities.
 */
public class SearchUtils {

    /** Private constructor (don't instantiate). */
    private SearchUtils() {
    }

    /**
     * Decomposes a string into tokens using whitespace characters as separators. Each quoted part of the string produces a single
     * token.
     * 
     * @param s
     *            the string to be tokenized.
     * @return the list of tokens.
     */
    public static List<String> getTokens(String s) {
        s = StringUtils.trim(StringUtils.defaultString(s));
        List<String> tokens = new ArrayList<String>();
        int length = s.length();
        StringBuffer buffer = new StringBuffer();
        boolean quoted = false;
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            if (c == '\"') {
                if (!quoted) {
                    extractToken(buffer, tokens);
                    quoted = true;
                } else {
                    extractToken(buffer, tokens);
                    quoted = false;
                }
            } else if (Character.isWhitespace(c)) {
                if (!quoted) {
                    extractToken(buffer, tokens);
                } else {
                    buffer.append(c);
                }
            } else {
                buffer.append(c);
            }
        }
        if (quoted) {
            tokens.addAll(getTokens(buffer.toString()));
        } else {
            extractToken(buffer, tokens);
        }
        return tokens;
    }

    /**
     * Extracts a token (if not empty) from a string buffer, moving it to a list of tokens and resetting the buffer.
     * 
     * @param buffer   the buffer holding a token.
     * @param tokens   the current list of tokens.
     */
    private static void extractToken(StringBuffer buffer, List<String> tokens) {
        if (buffer.length() > 0) {
            String token = buffer.toString();
            token = StringUtils.join(StringUtils.split(token), ' '); // normalize spaces
            if (token.length() > 0) {
                tokens.add(token);
            }
        }
        buffer.setLength(0);
    }

}
